home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000 #2
/
Ham Radio 2000 - Volume 2.iso
/
HAMV2
/
ANTENNA
/
YAGIU112
/
GA_LIB.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-15
|
7KB
|
337 lines
#include <string.h>
#ifndef GCC
#include <stdlib.h>
#endif
#include <values.h>
#include <math.h>
#include <sys/types.h>
#ifdef i386
#ifdef UNIX
#include <time.h>
#endif
#elif
#include <sys/time.h>
#endif
#ifdef i386
#ifndef DOS
#include <ieeefp.h> /* Needed for isnan() on PC running unix */
#endif
#endif
#include <errno.h>
#include "yagi.h"
typedef struct {
int parent1,parent2 ;
char *gene ;
double fitness ;
} GeneRecord ;
int population_size=0 ;
int gene_length=0 ;
int elite=1 ;
int ramp=0 ;
int PRINT=1 ;
double MX ;
/* double pmutate=0.4 ;
double pcross=0.6 ;
double psimplex=0.4 ;
double ptrans=0.2 ; */
double pmutate=0.1 ;
double pcross=0.9 ;
double psimplex=0.5 ;
double ptrans=0.03 ;
extern int errno;
GeneRecord *Pop1=NULL,*Pop2=NULL ;
void setprobs(double pm,double pc,double ps,double pt)
{
pmutate=pm ;
pcross=pc ;
psimplex=ps;
ptrans=pt ;
}
int GA_Free(void)
{
int a ;
if (Pop1!=NULL) {
for(a=0 ; a<population_size ;a++)
if (Pop1[a].gene!=NULL) free(Pop1[a].gene) ;
free((char *) Pop1) ;
}
if (Pop2!=NULL) {
for(a=0 ; a<population_size ;a++)
if (Pop2[a].gene!=NULL) free(Pop2[a].gene) ;
free((char *) Pop2) ;
}
}
int GA_Error(char *ErrorMsg)
{
int a ;
if (Pop1!=NULL) {
for(a=0 ; a<population_size ;a++)
if (Pop1[a].gene!=NULL) free(Pop1[a].gene) ;
free(Pop1) ;
}
if (Pop2!=NULL) {
for(a=0 ; a<population_size ;a++)
if (Pop2[a].gene!=NULL) free(Pop2[a].gene) ;
free(Pop2) ;
}
fprintf(stderr,"GA_LIB Error : %s \n\n",ErrorMsg) ;
exit(1) ;
}
double GetMax()
{
return(MX) ;
}
void SetPrint(int a)
{
PRINT=a;
}
void dump_pop1(FILE *fd,int generation,double max,double aver)
{
int a ;
if (PRINT==0) return ;
fprintf(fd,"Current contents of population: generation %d\n",generation);
for(a=0 ; a<gene_length ; a++) fprintf(fd,"-");
fprintf(fd,"------------------\n");
fprintf(fd,"Par1 Par2 Fitness Code\n");
for(a=0 ; a<population_size ; a++)
fprintf(fd,"%4d %4d %9.4f %s\n",Pop1[a].parent1,Pop1[a].parent2,Pop1[a].fitness,Pop1[a].gene);
fprintf(fd,"\n Maximum %9.4lf Average %9.4lf\n",max,aver);
for(a=0 ; a<gene_length ; a++) fprintf(fd,"-");
fprintf(fd,"------------------\n\n");
}
int Initialise(int PopSize, int GeneSize)
{
int a,b ;
char c[2] ;
c[1]=0 ;
/* srandom(time(&a)); */
ramp=0 ;
population_size=PopSize ;
gene_length=GeneSize+1 ;
/* limit population size */
if ((PopSize<20)||(PopSize>1000)) GA_Error("Bad parameters to Initialise") ;
/* Allocate memory for population 1 */
Pop1=(GeneRecord *)calloc(PopSize,sizeof(GeneRecord)) ;
/* Mem alloc error */
if (Pop1==NULL) GA_Error((char *)"Memory allocation for population 1") ;
/* Blank population array */
for (a=0 ; a<population_size ; a++) {
Pop1[a].gene=NULL ;
Pop1[a].parent1=0 ;
Pop1[a].parent2=0 ;
Pop1[a].fitness=0.0 ;
}
/* Allocate memory for genes */
for (a=0 ; a<population_size ; a++)
if ((Pop1[a].gene=malloc(gene_length))==NULL)
GA_Error("Cannot allocate gene in population 1");
/* Allocate memory for population 2 */
Pop2=(GeneRecord *)calloc(PopSize,sizeof(GeneRecord)) ;
/* Mem alloc error */
if (Pop2==NULL) GA_Error((char *)"Memory allocation for population 1") ;
/* Blank population array */
for (a=0 ; a<population_size ; a++) {
Pop2[a].gene=NULL ;
Pop2[a].parent1=0 ;
Pop2[a].parent2=0 ;
Pop2[a].fitness=0.0 ;
}
/* Allocate memory for genes */
for (a=0 ; a<population_size ; a++)
if ((Pop2[a].gene=malloc(gene_length))==NULL)
GA_Error("Cannot allocate gene in population 2");
/* Initialise genes */
for (a=0 ; a<population_size ; a++) {
for (b=0 ; b<GeneSize ; b++)
/* Pop1[a].gene[b]=(char)(48+(randint()&1)) ;XXXXXXXX */
Pop1[a].gene[b]=(char)(48+(randint()&1)) ;
Pop1[a].gene[GeneSize]=0 ;
}
#ifdef DEBUG
if(errno)
{
fprintf(stderr,"Errno =%d in Initialise() of ga_lib.c\n", errno);
exit(1);
}
#endif
return (0) ;
}
void crossover(char *s1,char *s2)
{
int point;
char duplic ;
/* only works for strings of same length */
if (strlen(s1)!=strlen(s2)) GA_Error((char *)"Gene length mismatch for crossover") ;
/* choose a point and swap tails of strings */
for (point=(randint()%(strlen(s1)-2))+1 ; point <strlen(s1) ; point++)
{
duplic=s1[point] ;
s1[point]=s2[point] ;
s2[point]=duplic ;
}
}
void mutate(char *s1)
{
/* flip a bit in at random point */
s1[randint()%strlen(s1)]^=1 ;
}
int ga_simplex(char *s1,char *s2, char *s3)
{
int point ;
for (point=0 ; point <(strlen(s1)-1) ; point++ )
if (s1[point]==s2[point])
s3[point]=s1[point] ;
else
s3[point]=s3[point]^1 ;
}
void swap(int *x,int *y)
{
int t ;
t=*x ;
*x=*y ;
*y=t ;
}
void Sort()
{
GeneRecord T ;
int outer,inner,moved;
for (outer=population_size-1; outer>0 ; outer--)
{
moved=0 ;
for (inner=0 ; inner<outer ; inner++)
{
if (Pop1[inner].fitness<Pop1[inner+1].fitness)
{
memcpy((char *) &T,(char *) &Pop1[inner],sizeof(GeneRecord)) ;
memcpy((char *) &Pop1[inner],(char *) &Pop1[inner+1],sizeof(GeneRecord)) ;
memcpy((char *) &Pop1[inner+1],(char *) &T,sizeof(GeneRecord)) ;
moved=1;
}
}
if (moved==0) break ;
}
}
void transloc(char *gene)
{
int a,point,gene_size ;
char *dup;
gene_size=gene_length-1 ;
point=randint()%gene_size ;
dup=strdup(gene) ;
for(a=0 ; a<gene_size ; a++) gene[a]=dup[(a+point)%gene_size] ;
free(dup);
}
int Selection(FILE *fd, int gen)
{
int a,b,c,select,d ;
double sigma,rd ;
GeneRecord *temp ;
double minfit,maxfit ;
FILE *tmp;
sigma=0.0 ;
minfit=MAXDOUBLE ;
maxfit=-minfit ;
/* minfit=1e308; maxfit=-1e308; XXXXXXXXXXXXXXXXXXXXXX */
for(a=0 ; a<population_size ; a++ )
{
Pop1[a].fitness=Objective(Pop1[a].gene) ;
if (Pop1[a].fitness<minfit) minfit=Pop1[a].fitness ;
if (Pop1[a].fitness>maxfit) maxfit=Pop1[a].fitness ;
sigma+=Pop1[a].fitness ;
}
MX=maxfit ;
Sort() ;
dump_pop1(fd,gen,maxfit,sigma/population_size);
for(a=0 ; a<population_size ; a++ )
{
if(minfit!=maxfit)
{
Pop1[a].fitness=((Pop1[a].fitness-minfit)*99.0/(maxfit-minfit))+1.0 ;
}
}
ramp++ ;
sigma=0.0 ;
for(a=0 ; a<population_size ; a++ )
sigma+=Pop1[a].fitness ;
c=0 ;
for(a=0 ; a<population_size ; a++ )
{
b=(int) (Pop1[a].fitness*population_size/sigma) ;
for (d=0 ; d<b ; d++)
strcpy(Pop2[c++].gene,Pop1[a].gene) ;
}
for(d=c ; d<population_size ; d++)
{
b=randint()%population_size ;
strcpy(Pop2[d].gene,Pop1[b].gene) ;
}
for(a=0 ; a<population_size ;a++)
{
if (randreal()<pmutate) mutate(Pop2[a].gene) ;
if (randreal()<ptrans) transloc(Pop2[a].gene) ;
}
temp=Pop1 ;
Pop1=Pop2 ;
Pop2=temp ;
for(a=2 ; a<population_size ; a+=2 )
{
b=randint()%population_size ;
c=randint()%population_size ;
strcpy(Pop2[a].gene,Pop1[b].gene);
strcpy(Pop2[a+1].gene,Pop1[c].gene);
if (randreal()<pcross)
{
crossover(Pop2[a].gene,Pop2[a+1].gene) ;
Pop2[a].parent2=Pop2[a+1].parent1 ;
Pop2[a+1].parent2=Pop2[a].parent1 ;
} else {
Pop2[a].parent2=Pop2[a].parent1 ;
Pop2[a+1].parent2=Pop2[a+1].parent1 ;
}
}
if (randreal()<psimplex) {
a=randint()%population_size ;
b=randint()%population_size ;
c=randint()%population_size ;
if (Pop1[a].fitness<Pop1[b].fitness)
swap(&a,&b) ;
if (Pop1[b].fitness<Pop1[c].fitness)
swap(&b,&c) ;
if (Pop1[a].fitness<Pop1[b].fitness)
swap(&a,&b) ;
ga_simplex(Pop1[a].gene,Pop1[b].gene,Pop2[c].gene);
}
temp=Pop1 ;
Pop1=Pop2 ;
Pop2=temp ;
return 0 ;
}